import React from 'react';
import { Responsive, WidthProvider } from 'react-grid-layout';
import { Button, Input, Modal, Form, Select, Popover } from 'antd';
import GridContent from './GridContent';

import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';

// 具体的各种配置可以查看 https://github.com/STRML/react-grid-layout
const ResponsiveReactGridLayout = WidthProvider(Responsive);
@Form.create()
class GridLayout extends React.Component {
  static defaultProps = {
    className: 'layout',
    rowHeight: 100,
    cols: { lg: 24, md: 24, sm: 24, xs: 24, xxs: 24 },
  };

  state = {
    currentBreakpoint: 'lg',
    compactType: null,
    settingVisible: false,
    // 所有的布局，这是每个拖拽div在不同页面像素下的坐标位置
    gridContents: { lg: [], md: [], sm: [], xs: [], xxs: [] },
    // 所有的样式
    styles: new Map(),
    // 所有的内容
    contents: new Map(),
    // 重点：这里按道理只需要把gridContetns，styles，contents保存下来就可以恢复原先的布局了。

    // 当前的样式以及当前样式对象的map key，设置样式的时候需要用到
    currentStyle: {},
    currentIndex: '-1',
    currentContent: {},
    colorVisible: false,
    localVars: {
      borderColor: '',
    },
    counter: 0,
  };

  constructor(props) {
    super(props);
    this.formLayout = {
      labelCol: { span: 5 },
      wrapperCol: { span: 18 },
    };
    // 这是设置样式的供选择九种颜色
    this.colorList = [
      'rgb(80, 158, 227)',
      'rgb(156, 193, 119)',
      'rgb(169, 137, 197)',
      'rgb(239, 140, 140)',
      'rgb(249, 212, 92)',
      'rgb(242, 168, 111)',
      'rgb(152, 217, 217)',
      'rgb(113, 114, 173)',
      'rgb(116, 131, 143)',
    ];
  }

  componentDidMount() {}

  // 这个是在页面像素变化的时候，调用的方法
  onBreakpointChange = breakpoint => {
    this.setState({
      currentBreakpoint: breakpoint,
    });
  };

  // 点击添加按钮增加state当中div的布局内容
  onAddItem = () => {
    const { counter, gridContents, currentBreakpoint, styles, contents } = this.state;

    gridContents[currentBreakpoint].push({
      i: `${counter}`,
      x: 0,
      y: 0,
      w: 8,
      h: 2,
    });

    styles.set(`${counter}`, {
      menuStyle: {
        position: 'absolute',
        right: '2px',
        top: 0,
        cursor: 'pointer',
      },
      basicStyle: { fontSize: '16px' },
      borderStyle: {
        borderWidth: '1px',
        borderColor: 'rgb(80, 158, 227)',
        borderStyle: 'solid',
        borderRadius: '0px',
      },
      background: { backgroundColor: 'rgb(240, 242, 245)' },
    });

    contents.set(`${counter}`, {
      title: '这是我的初始化标题',
      type: 'graph',
      graphType: 'BarChart',
    });

    this.setState({
      gridContents,
      styles,
      contents,
      counter: counter + 1,
    });
  };

  // 在改变布局的时候，将各个{ lg: [], md: [], sm: [], xs: [], xxs: [] }像素下的布局都设置成一致，避免缩小放大页面的时候布局变化
  onLayoutChange = layout => {
    const { gridContents } = this.state;
    const keys = Object.keys(gridContents);
    keys.map(item => {
      gridContents[item] = layout;
      return null;
    });
    this.setState({
      gridContents,
    });
  };

  // 这个是形成一个拖拽div的方法，使用map遍历全部state当中gridContents即可按照state恢复div布局
  createElement = (el, style, content) => {
    const { i } = el;
    return (
      <div
        key={i}
        data-grid={el}
        style={{ ...style.borderStyle, ...style.background, cursor: 'move' }}
      >
        <GridContent
          id={i}
          onRemoveItem={this.onRemoveItem}
          onChangeStyle={this.onChangeStyle}
          style={style}
          content={content}
        />
      </div>
    );
  };

  // 删除state当中的布局
  onRemoveItem = i => {
    const { gridContents, currentBreakpoint } = this.state;
    let deleteIndex = -1;
    gridContents[currentBreakpoint].filter((item, index) => {
      if (item.i === i) {
        deleteIndex = index;
      }
      return null;
    });
    if (deleteIndex !== -1) {
      gridContents[currentBreakpoint].splice(deleteIndex, 1);
    }

    this.setState({ gridContents });
  };

  // 选择某个div设置样式时，将当前选中的div内容、样式以及对应的map key保存下来
  onChangeStyle = i => {
    const { styles, contents } = this.state;
    let { localVars } = this.state;
    this.setState({ settingVisible: true });
    this.setState({ currentStyle: styles.get(i), currentIndex: i });
    this.setState({ currentContent: contents.get(i) });

    localVars = { ...localVars, borderColor: styles.get(i).borderStyle.borderColor };
    this.setState({ localVars });
  };

  // 这是在提交修改样式之后的处理逻辑
  changeStyle = () => {
    const { styles, currentIndex, currentStyle: newCurrentStyle, localVars, contents } = this.state;
    let { currentContent } = this.state;
    const { form } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const newFormValues = { ...fieldsValue };
      newCurrentStyle.basicStyle = {
        ...newCurrentStyle.basicStyle,
        fontSize: newFormValues.fontSize,
      };
      newCurrentStyle.borderStyle = {
        ...newCurrentStyle.borderStyle,
        borderWidth: newFormValues.borderWidth,
        borderStyle: newFormValues.borderStyle,
        borderRadius: newFormValues.borderRadius,
        borderColor: localVars.borderColor,
      };
      currentContent = { ...currentContent, title: newFormValues.titleContent };
      styles.set(currentIndex, newCurrentStyle);
      contents.set(currentIndex, currentContent);
      this.setState({ styles, contents, settingVisible: false });
    });
  };

  handleVisibleChange = visible => {
    this.setState({ colorVisible: visible });
  };

  // 设置样式当中选择颜色的操作
  chooseColor = color => {
    let { localVars } = this.state;
    localVars = { ...localVars, borderColor: color };
    this.setState({ colorVisible: false });
    this.setState({ localVars });
  };

  render() {
    const {
      currentBreakpoint,
      gridContents,
      compactType,
      settingVisible,
      styles,
      currentStyle,
      colorVisible,
      contents,
      localVars,
      currentContent,
    } = this.state;
    const { form } = this.props;
    // 颜色选择器的遍历生成
    const content = (
      <div>
        <div style={{ display: 'flex', flexWrap: 'wrap', width: '120px' }}>
          {this.colorList.map(item => {
            return (
              <div style={{ padding: '4px', cursor: 'pointer' }} key={item}>
                <div
                  style={{
                    width: '32px',
                    height: '32px',
                    backgroundColor: `${item}`,
                    borderRadius: '4px',
                  }}
                  onClick={() => this.chooseColor(item)}
                />
              </div>
            );
          })}
        </div>
      </div>
    );
    return (
      <div>
        <Button onClick={this.onAddItem}>添加内容</Button>
        <ResponsiveReactGridLayout
          {...this.props}
          layouts={gridContents}
          onBreakpointChange={this.onBreakpointChange}
          onLayoutChange={this.onLayoutChange}
          compactType={compactType}
          preventCollision={!compactType}
        >
          {gridContents[currentBreakpoint].map(item => {
            return this.createElement(item, styles.get(item.i), contents.get(item.i));
          })}
        </ResponsiveReactGridLayout>
        {/* 以下的对话框就是样式设置页面 */}
        <Modal
          destroyOnClose
          title="样式设置界面"
          visible={settingVisible}
          onOk={() => {
            this.changeStyle();
          }}
          onCancel={() => {
            this.setState({ settingVisible: false });
          }}
        >
          <Form.Item key="titleContent" {...this.formLayout} label="标题内容">
            {form.getFieldDecorator('titleContent', {
              initialValue: currentContent && currentContent.title,
            })(<Input placeholder="设置标题" />)}
          </Form.Item>
          <Form.Item key="fontSize" {...this.formLayout} label="标题字体大小">
            {form.getFieldDecorator('fontSize', {
              initialValue: currentStyle.basicStyle && currentStyle.basicStyle.fontSize,
            })(<Input placeholder="设置字体大小" />)}
          </Form.Item>
          <Form.Item key="borderWidth" {...this.formLayout} label="边框粗细">
            {form.getFieldDecorator('borderWidth', {
              initialValue: currentStyle.borderStyle && currentStyle.borderStyle.borderWidth,
            })(
              <Select>
                <Select.Option value="0px">
                  <div style={{ border: '0px solid black ', width: '60px', height: '30px' }}>
                    0px
                  </div>
                </Select.Option>
                <Select.Option value="1px">
                  <div style={{ border: '1px solid black ', width: '60px', height: '30px' }}>
                    1px
                  </div>
                </Select.Option>
                <Select.Option value="2px">
                  <div style={{ border: '2px solid black ', width: '60px', height: '30px' }}>
                    2px
                  </div>
                </Select.Option>
                <Select.Option value="5px">
                  <div style={{ border: '5px solid black ', width: '60px', height: '30px' }}>
                    5px
                  </div>
                </Select.Option>
              </Select>
            )}
          </Form.Item>
          <Form.Item key="borderStyle" {...this.formLayout} label="边框类型">
            {form.getFieldDecorator('borderStyle', {
              initialValue: currentStyle.borderStyle && currentStyle.borderStyle.borderStyle,
            })(
              <Select>
                <Select.Option value="dotted">
                  <div style={{ border: '1px dotted black ', width: '60px', height: '30px' }}>
                    点边框
                  </div>
                </Select.Option>
                <Select.Option value="dashed">
                  <div style={{ border: '1px dashed black ', width: '60px', height: '30px' }}>
                    虚线边框
                  </div>
                </Select.Option>
                <Select.Option value="solid">
                  <div style={{ border: '1px solid black ', width: '60px', height: '30px' }}>
                    实线边框
                  </div>
                </Select.Option>
              </Select>
            )}
          </Form.Item>
          <Form.Item key="borderRadius" {...this.formLayout} label="边框圆角">
            {form.getFieldDecorator('borderRadius', {
              initialValue: currentStyle.borderStyle && currentStyle.borderStyle.borderRadius,
            })(
              <Select>
                <Select.Option value="0px">
                  <div
                    style={{
                      border: '1px solid black ',
                      borderRadius: '0px',
                      width: '60px',
                      height: '30px',
                    }}
                  >
                    0px
                  </div>
                </Select.Option>
                <Select.Option value="1px">
                  <div
                    style={{
                      border: '1px solid black ',
                      borderRadius: '1px',
                      width: '60px',
                      height: '30px',
                    }}
                  >
                    1px
                  </div>
                </Select.Option>
                <Select.Option value="5px">
                  <div
                    style={{
                      border: '1px solid black ',
                      borderRadius: '5px',
                      width: '60px',
                      height: '30px',
                    }}
                  >
                    5px
                  </div>
                </Select.Option>
                <Select.Option value="10px">
                  <div
                    style={{
                      border: '1px solid black ',
                      borderRadius: '10px',
                      width: '60px',
                      height: '30px',
                    }}
                  >
                    10px
                  </div>
                </Select.Option>
              </Select>
            )}
          </Form.Item>

          <Form.Item key="borderColor" {...this.formLayout} label="边框颜色">
            <div style={{ display: 'inline-block', marginTop: '5px' }}>
              <div
                style={{
                  borderRadius: '4px',
                  border: '1px solid #d7dbde',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  width: '33px',
                  height: '33px',
                }}
              >
                <Popover
                  content={content}
                  trigger="click"
                  visible={colorVisible}
                  onVisibleChange={this.handleVisibleChange}
                >
                  <div
                    style={{
                      width: '21px',
                      height: '21px',
                      backgroundColor: `${localVars.borderColor}`,
                      borderRadius: '2.625px',
                      cursor: 'pointer',
                    }}
                  />
                </Popover>
              </div>
            </div>
          </Form.Item>
        </Modal>
      </div>
    );
  }
}

export default GridLayout;
